﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Support.DTO;
using System.Data;
using System.Data.SqlClient;
using Support.Enums;

namespace DataAccess
{
    public class UsuarioDAL : BaseSQLDAL
    {
        public UsuarioDTO GetUsuario(string username, string password)
        {
            try
            {
                UsuarioDTO usuario = new UsuarioDTO();
                CreateCommand("Usuario_ObtenerPorCredenciales", true);
                AddCmdParameter("@UserName", username, ParameterDirection.Input);
                AddCmdParameter("@Password", password, ParameterDirection.Input);

                ExecuteReader();
                while (Read())
                {
                    usuario = FillDTO(GetDataReader());
                }
                return usuario;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                DisposeCommand();
                DisposeDataReader();
                CloseConnection();
            }
        }

        private UsuarioDTO FillDTO(SqlDataReader reader)
        {
            return new UsuarioDTO()
            {
                Id = reader.GetInt32(reader.GetOrdinal("IdUsuario")),
                UserName = reader.GetString(reader.GetOrdinal("Usuario")),
                Password = reader.GetString(reader.GetOrdinal("Contrasenia")),
                Nombre = reader.GetString(reader.GetOrdinal("Nombre")),
                Apellido = reader.GetString(reader.GetOrdinal("Apellido")),
                Rol = reader.GetInt32(reader.GetOrdinal("IdRol")),
                Activo = reader.GetInt32(reader.GetOrdinal("Activo")),
                RolNombre = reader.GetString(reader.GetOrdinal("RolNombre"))
            };
        }

        
        public int GuardarUsuario(UsuarioDTO usuario)
        {
            try
            {
                CreateCommand("Usuario_Insertar", true);
                AddCmdParameter("@Usuario", usuario.UserName, ParameterDirection.Input);
                AddCmdParameter("@Nombre", usuario.Nombre, ParameterDirection.Input);
                AddCmdParameter("@Apellido", usuario.Apellido, ParameterDirection.Input);
                AddCmdParameter("@Rol", usuario.Rol, ParameterDirection.Input);
                AddCmdParameter("@Password", usuario.Password, ParameterDirection.Input);

                ExecuteReader();
                Read();
                int result = Convert.ToInt32(GetOutResult("usuario_id"));
                return result > 0 ? result : -1;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                DisposeCommand();
                DisposeDataReader();
                CloseConnection();
            }
        }

        public int CambiarPassword(int userId, string oldPassword, string newPassword)
        {
            try
            {
                CreateCommand("UpdateUsuarioPassword", true);
                AddCmdParameter("@Id", userId, ParameterDirection.Input);
                AddCmdParameter("@PasswordAnterior", oldPassword, ParameterDirection.Input);
                AddCmdParameter("@PasswordNuevo", newPassword, ParameterDirection.Input);

                ExecuteReader();
                Read();
                return Convert.ToInt32(GetOutResult("result"));
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                DisposeCommand();
                DisposeDataReader();
                CloseConnection();
            }
        }

        public int ActivarUsuario(int userId, string newPassword)
        {
            try
            {
                CreateCommand("ActivarUsuario", true);
                AddCmdParameter("@Id", userId, ParameterDirection.Input);
                AddCmdParameter("@Password", newPassword, ParameterDirection.Input);

                ExecuteReader();
                Read();
                return Convert.ToInt32(GetOutResult("result"));
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                DisposeCommand();
                DisposeDataReader();
                CloseConnection();
            }
        }

        public List<RolDTO> GetRoles()
        {
            List<RolDTO> roles = new List<RolDTO>();

            try
            {

                CreateCommand("Rol_Listado", true);
               
                ExecuteReader();
                while (Read())
                {
                    roles.Add(FillRolDTO(GetDataReader()));
                }
                return roles;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                DisposeCommand();
                DisposeDataReader();
                CloseConnection();
            }
        }

        private RolDTO FillRolDTO(SqlDataReader reader)
        {
            return new RolDTO()
            {
                RolId = reader.GetInt32(reader.GetOrdinal("IdRol")),
                Nombre = reader.GetString(reader.GetOrdinal("Nombre"))
            };
        }

        public List<UsuarioDTO> BuscarUsuarios(string nombre, string apellido, string username, int rol)
        {
            var usuarios = new List<UsuarioDTO>();

            try
            {
                CreateCommand("Usuario_Buscar", true);
                AddCmdParameter("@Nombre", string.IsNullOrEmpty(nombre) ? string.Empty : nombre, ParameterDirection.Input);
                AddCmdParameter("@Apellido", string.IsNullOrEmpty(apellido) ? string.Empty : apellido, ParameterDirection.Input);
                AddCmdParameter("@NombreUsuario", string.IsNullOrEmpty(username) ? string.Empty : username, ParameterDirection.Input);
                AddCmdParameter("@Rol", rol, ParameterDirection.Input);

                ExecuteReader();
                while (Read())
                {
                    usuarios.Add(FillDTO(GetDataReader()));
                }
                return usuarios;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                DisposeCommand();
                DisposeDataReader();
                CloseConnection();
            }
        }

        public bool ModificarUsuario(UsuarioDTO usuario)
        {
            try
            {
                CreateCommand("Usuario_Modificar", true);
                AddCmdParameter("@Id", usuario.Id, ParameterDirection.Input);
                AddCmdParameter("@Usuario", usuario.UserName, ParameterDirection.Input);
                AddCmdParameter("@Nombre", usuario.Nombre, ParameterDirection.Input);
                AddCmdParameter("@Apellido", usuario.Apellido, ParameterDirection.Input);
                AddCmdParameter("@Rol", usuario.Rol, ParameterDirection.Input);

                ExecuteReader();
                Read();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
            finally
            {
                DisposeCommand();
                DisposeDataReader();
                CloseConnection();
            }
        }

        public bool EliminarUsuario(int usuarioId)
        {
            try
            {
                CreateCommand("Usuario_Eliminar", true);
                AddCmdParameter("@Id", usuarioId, ParameterDirection.Input);

                ExecuteReader();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
            finally
            {
                DisposeCommand();
                CloseConnection();
            }
        }

        public UsuarioDTO ObtenerUsuarioPorId(int usuarioId)
        {
            UsuarioDTO usuario = new UsuarioDTO();

            try
            {
                CreateCommand("Usuario_ObtenerPorId", true);
                AddCmdParameter("@UsuarioId", usuarioId, ParameterDirection.Input);

                ExecuteReader();
                while (Read())
                {
                    usuario = FillDTO(GetDataReader());
                }
                return usuario;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                DisposeCommand();
                DisposeDataReader();
                CloseConnection();
            }
        }
    }
}
